package com.chatplus.application.aiprocessor.listener.impl;

import cn.hutool.extra.spring.SpringUtil;
import com.chatplus.application.aiprocessor.enumeration.MessageTypeEnum;
import com.chatplus.application.common.logging.SouthernQuietLogger;
import com.chatplus.application.common.logging.SouthernQuietLoggerFactory;
import com.chatplus.application.aiprocessor.channel.chat.xunfei.dto.XunFeiMsgDTO;
import com.chatplus.application.aiprocessor.channel.chat.xunfei.dto.XunFeiResponseDTO;
import com.chatplus.application.aiprocessor.util.ChatAiUtilHandler;
import com.chatplus.application.enumeration.AiPlatformEnum;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okhttp3.WebSocket;
import okhttp3.WebSocketListener;
import org.jetbrains.annotations.NotNull;
import org.springframework.web.socket.WebSocketSession;

import java.io.IOException;
import java.util.Objects;

/**
 * 讯飞星火监听器
 *
 * @author chj
 * @date 2024/1/4
 **/
public class XunFeiEventSourceListener extends WebSocketListener {
    private static final SouthernQuietLogger LOGGER = SouthernQuietLoggerFactory.getLogger(XunFeiEventSourceListener.class);
    StringBuilder reply = new StringBuilder();
    protected final ChatAiUtilHandler chatAiUtilHandler;

    public XunFeiEventSourceListener(WebSocketSession session, AiPlatformEnum platform, String prompt) {
        chatAiUtilHandler = new ChatAiUtilHandler(session, platform, prompt);
    }

    @Override
    public void onOpen(@NotNull WebSocket webSocket, @NotNull Response response) {
        LOGGER.message("连接成功").context("response", response).info();
        chatAiUtilHandler.sendMessage(MessageTypeEnum.WS_START.getValue());
        super.onOpen(webSocket, response);
    }

    @Override
    public void onMessage(@NotNull WebSocket webSocket, @NotNull String text) {
        super.onMessage(webSocket, text);
        LOGGER.message("讯飞返回数据").context("data", text).info();

        ObjectMapper objectMapper = SpringUtil.getBean(ObjectMapper.class);
        // 将大模型回复的 JSON 文本转为 ResponseDTO 对象
        XunFeiResponseDTO responseData = null;
        try {
            responseData = objectMapper.readValue(text, XunFeiResponseDTO.class);
            // 如果响应数据中的 header 的 code 值不为 0，则表示响应错误
            if (responseData.getHeader().getCode() != 0) {
                // 日志记录
                LOGGER.message("发生错误，错误码为：" + responseData.getHeader().getCode() + "; " + "信息：" + responseData.getHeader().getMessage()).error();
                return;
            }
            // 将回答进行拼接
            for (XunFeiMsgDTO msgDTO : responseData.getPayload().getChoices().getText()) {
                String result = msgDTO.getContent();
                chatAiUtilHandler.sendMessage(result);
                reply.append(result);
            }
            // 对最后一个文本结果进行处理
            if (2 == responseData.getHeader().getStatus()) {
                chatAiUtilHandler.saveChatHistory(reply.toString(),null);
                chatAiUtilHandler.sendMessage(MessageTypeEnum.WS_END.getValue());
            }
        } catch (JsonProcessingException e) {
            chatAiUtilHandler.replyErrorMessage("服务端发生异常，等待管理员修复!",false);
            LOGGER.message("JSON 解析错误").exception(e).error();
        }
    }

    @Override
    public void onFailure(@NotNull WebSocket webSocket, @NotNull Throwable t, Response response) {
        if (Objects.isNull(response)) {
            return;
        }
        try {
            ResponseBody body = response.body();
            if (Objects.nonNull(body)) {
                String bodyStr = body.string();
                LOGGER.message("连接异常").context("data", bodyStr).exception(t).error();
                chatAiUtilHandler.replyErrorMessage("服务端发生异常，等待管理员修复,第三方返回: " + bodyStr,true);

            } else {
                LOGGER.message("连接异常").context("data", response).exception(t).error();
                chatAiUtilHandler.replyErrorMessage("服务端发生异常，等待管理员修复!",true);
            }
        } catch (IOException e) {
            LOGGER.message("连接异常").exception(e).error();
        }
        super.onFailure(webSocket, t, response);
    }

    @Override
    public void onClosed(@NotNull WebSocket webSocket, int code, @NotNull String reason) {
        LOGGER.message("关闭连接").info();
        super.onClosed(webSocket, code, reason);
    }
}